/*
 * Face.cpp
 *
 *  Created on: Oct 24, 2012
 *      Author: tony
 */

#include "../face/Face.h"

Face::Face() {
	this->state = NULL;
	this->name = NULL;
    this->allowUpdate = true;
    this->autorelease();

    this->states = CCDictionary::create();
	CC_SAFE_RETAIN(this->states);
}

Face::~Face() {
}

void Face::onEnter() {
    CCSprite::onEnter();
}

void Face::onExit() {
    CCSprite::onExit();
    CC_SAFE_RELEASE(this->states);
    this->removeAllChildrenWithCleanup(true);
}

bool Face::init() {
    return Sprite::init();
}

bool Face::initWithFile(const std::string& filename) {
    return Sprite::initWithFile(filename);
}

bool Face::initWithSpriteFrameName(const std::string& spriteFrameName) {
    return Sprite::initWithSpriteFrameName(spriteFrameName);
}

Action* Face::getState() {
	return this->state;
}

Action* Face::getState(const std::string& stateName) {
	return (Action*) this->states->objectForKey(stateName);
}

void Face::setState(Action* s) {
	if (this->state != s) {
		if (this->state != NULL) {
			this->stopAction(state);
		}
		if (s != NULL) {
			this->state = s;
			this->runAction(this->state);
		} else {
			this->state = NULL;
		}
	}
}

void Face::setState(const std::string& stateName) {
    this->setState(this->getState(stateName));
}

void Face::registerState(const std::string& stateName, const std::string& patternName) {
	this->registerState(stateName, createState(patternName, 0.8f, true));
}

void Face::registerState(const std::string& stateName, Action* action) {
	if (action != NULL) {
		this->states->setObject(action, stateName);
	}
}

void Face::removeState(const std::string &stateName) {
    this->states->removeObjectForKey(stateName);
}

Action* Face::createState(const std::string&  patternName, float frameDuration, bool forever) {
	return this->createState(patternName, 4, frameDuration, forever, false);
}

Action* Face::createState(const std::string&  patternName, int frameNumber, float frameDuration, bool forever, bool reverse) {
	return this->createState(patternName, 1, frameNumber, frameDuration, forever, reverse);
}

Action* Face::createState(const std::string& patternName, int startFrame, int endFrame, float frameDuration, bool forever, bool reverse) {
    Vector<SpriteFrame*> *framesVector = this->createFrameVector(patternName,startFrame,endFrame);
    //xu ly reverse
	if (reverse) {
		int framesSize = framesVector->size();
		for(int i = framesSize - 1; i >= 0; i--) {
			framesVector->pushBack(framesVector->at(i));
		}
	}
    float delay = frameDuration / framesVector->size();
    Animation* animation = Animation::createWithSpriteFrames(*framesVector, delay,forever);
	Animate* animate = Animate::create(animation);
	Action* action = NULL;
	if (forever) {
		action = RepeatForever::create(animate);
	} else {
		action = (Action*) animate;
	}
	return action;
}

Vector<SpriteFrame*>* Face::createFrameVector(const std::string& patternName, int startFrame, int endFrame) {
	SpriteFrameCache *spriteFrameCache = SpriteFrameCache::getInstance();
    Vector<SpriteFrame*>*framesVector = new Vector<SpriteFrame*>;
	char frameName[128];
	for(int i = startFrame; i <= endFrame; i++){
		sprintf(frameName, patternName.c_str(), i);
		framesVector->pushBack(spriteFrameCache->getSpriteFrameByName(frameName));
	}
	return framesVector;
}
